﻿using System;
using System.Collections.ObjectModel;
using System.Device.Location;
using CustomerList.Model;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using MyMeetup.Entities;

namespace MyMeetup.ViewModels
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class SearchPageViewModel : ViewModelBase
    {
        private DataService _dataService;
        private INavigationService _navigationService;

        public RelayCommand SearchClick { get; private set; }
        public RelayCommand GroupPageCommand { get; private set; }

        GeoCoordinate location;

        public string ApplicationTitle
        {
            get { return "my meetup"; }
        }

        public string PageName
        {
            get { return "find meetups"; }
        }


        /// <summary>
        /// Initializes a new instance of the SearchPageViewModel class.
        /// </summary>
        public SearchPageViewModel()
        {
            _dataService = new DataService();
            _navigationService = new NavigationService();
            SearchClick = new RelayCommand(Search);
            GroupPageCommand = new RelayCommand(GetGroup);
        
            ////if (IsInDesignMode)
            ////{
            ////    // Code runs in Blend --> create design time data.
            ////}
            ////else
            ////{
            ////    // Code runs "for real": Connect to service, etc...
            ////}
        }


        private bool _isInErrorState;
        private void ErrorCallbackInternal(RequestError error)
        {
            if(_isInErrorState) return;
            _isInErrorState = true;
            ResponseHelper.ErrorCallback(error);
        }


        private void Search()
        {
            _isInErrorState = false;

            if(App.Settings.UseLocServices == false)
            {
                var e = new RequestError()
                            {
                                problem = "Location Services Not Enabled",
                                details = "You need to enable location services to search for meetup groups near you"
                            };
                ErrorCallbackInternal(e);
                return;
            }

            var immediate = new ImmediateLocation(l =>
                                                      {
                                                          location = l;
                                                          _dataService.SearchForGroups(SanitizeTopic(SearchText),
                                                                                       location, App.Settings.SearchRadius,
                                                                                       (x) => GetSearchResults(x), ErrorCallbackInternal);
                                                      });
            immediate.GetLocation();
        }


        


        private void GetSearchResults(ObservableCollection<GroupSearchItem> results )
        {
            if (results.Count == 0)
                ErrorCallbackInternal(new RequestError() {details = "Your search did not contain any results", problem = "Search"});
            SearchResults = results;
        }


        private void GetGroup()
        {
            if (SelectedGroup == null) return;
            _dataService.GetGroupById(int.Parse(SelectedGroup.id), (x) =>
                                                                       {
                                                                           CurrentGroup = x;
                                                                           GoToGroupPage();
                                                                       }, ErrorCallbackInternal);
        }

        private void GoToGroupPage()
        {
            _navigationService.NavigateTo(new Uri("/PanoramaGroupPage.xaml", UriKind.Relative));

        }

        private string SanitizeTopic(string topic)
        {
            return topic.Replace(' ', '-');
        }


        /// <summary>
        /// The <see cref="SearchText" /> property's name.
        /// </summary>
        public const string SearchTextPropertyName = "SearchText";

        private string _searchText = "";

        /// <summary>
        /// Gets the SearchText property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string SearchText
        {
            get
            {
                return _searchText;
            }

            set
            {
                if (_searchText == value)
                {
                    return;
                }

                var oldValue = _searchText;
                _searchText = value;


                // Update bindings, no broadcast
                RaisePropertyChanged(SearchTextPropertyName);

            }
        }



        /// <summary>
        /// The <see cref="SearchResults" /> property's name.
        /// </summary>
        public const string SearchResultsPropertyName = "SearchResults";

        private ObservableCollection<GroupSearchItem> _searchResults;

        /// <summary>
        /// Gets the SearchResults property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public ObservableCollection<GroupSearchItem> SearchResults
        {
            get
            {
                return _searchResults;
            }

            set
            {
                if (_searchResults == value)
                {
                    return;
                }

                var oldValue = _searchResults;
                _searchResults = value;


                // Update bindings, no broadcast
                RaisePropertyChanged(SearchResultsPropertyName);

                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                //RaisePropertyChanged(SearchResultsPropertyName, oldValue, value, true);
            }
        }




        /// <summary>
        /// The <see cref="SelectedGroup" /> property's name.
        /// </summary>
        public const string SelectedGroupPropertyName = "SelectedGroup";

        private GroupSearchItem _selectedGroup;

        /// <summary>
        /// Gets the SelectedGroup property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public GroupSearchItem SelectedGroup
        {
            get
            {
                return _selectedGroup;
            }

            set
            {
                if (_selectedGroup == value)
                {
                    return;
                }

                var oldValue = _selectedGroup;
                _selectedGroup = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(CurrentGroupPropertyName);

            }
        }




        /// <summary>
        /// The <see cref="CurrentGroup" /> property's name.
        /// </summary>
        public const string CurrentGroupPropertyName = "CurrentGroup";

        private IGroup _currentGroup;

        /// <summary>
        /// Gets the CurrentGroup property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public IGroup CurrentGroup
        {
            get
            {
                return _currentGroup;
            }

            set
            {
                if (_currentGroup == value)
                {
                    return;
                }

                var oldValue = _currentGroup;
                _currentGroup = value;


                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                RaisePropertyChanged(CurrentGroupPropertyName, oldValue, value, true);
            }
        }

    }
}